import datetime
import itertools

import webapp2
import jinja2

from google.appengine.ext import ndb
from google.appengine.api import users

from eppistor.model import StorageUnit, Container, VialGroup, Vial

templates = jinja2.Environment(loader=jinja2.FileSystemLoader("templates"),
    autoescape=True)

def render(request_handler, template, **kwargs):
    request_handler.response.out.write(templates.get_template(template).render(**kwargs))

class Index(webapp2.RequestHandler):
    def get(self):
        render(self, "index.html",
            containers=Container.query().fetch(),
            storage_units=StorageUnit.query().fetch())

class StorageUnitForm(webapp2.RequestHandler):
    def get(self, action):
        urlsafe_key = self.request.get("key")
        su = None
        if urlsafe_key != "":
            k = ndb.Key(urlsafe=urlsafe_key)
            su = k.get()
            # TODO: validate access rights
            # TODO: validate its storage unit

        template = "storage_unit_form.html"
        containers = None
        if action == "view" and su is not None:
            template = "storage_unit.html"
            containers = dict((slot, list(group)) for slot, group in \
                itertools.groupby(su.query_containers().fetch(),
                lambda c: c.slot if c.slot in su.slots else ""))

        render(self, template, storage_unit=su, containers=containers)

    def post(self, action):
        urlsafe_key = self.request.get("key")
        action = self.request.get("action")
        if self.request.get("action") == "Delete":
            k = ndb.Key(urlsafe=urlsafe_key)
            k.delete()
            self.redirect("/")
            return
        elif action != "Cancel":
            if urlsafe_key != "":
                k = ndb.Key(urlsafe=urlsafe_key)
                su = k.get()
                # TODO: validate access rights
                # TODO: validate its storage unit
            else:
                su = StorageUnit()

            su.name = self.request.get("name")
            su.description = self.request.get("description")
            su.location = self.request.get("location")
            su.slots = self.request.get("slots").splitlines() # TODO: validation, skip empty lines
            su.put()
            urlsafe_key = su.key.urlsafe()

        if urlsafe_key != "":
            self.redirect("/storage_unit/view?key=" + urlsafe_key)
        else:
            self.redirect("/")


class ContainerForm(webapp2.RequestHandler):
    def get(self, action):
        urlsafe_key = self.request.get("key")
        container = None
        if urlsafe_key != "":
            k = ndb.Key(urlsafe=urlsafe_key)
            container = k.get()
            # TODO: validate access rights
            # TODO: validate it is a container

        template = "container_form.html"
        storage_units = StorageUnit.query().fetch()
        if action == "view" and container is not None:
            template = "container.html"

        render(self, template, container=container, storage_units=storage_units)

    def post(self, action):
        urlsafe_key = self.request.get("key")
        action = self.request.get("action")
        if self.request.get("action") == "Delete":
            k = ndb.Key(urlsafe=urlsafe_key)
            k.delete()
            self.redirect("/")
            return
        elif action != "Cancel":
            if urlsafe_key != "":
                k = ndb.Key(urlsafe=urlsafe_key)
                container = k.get()
                # TODO: validate access rights
                # TODO: validate it is a container
            else:
                container = Container()
                container.size_x = 8
                container.size_y = 8
                container.owner = users.get_current_user()

            container.name = self.request.get("name")
            container.description = self.request.get("description")
            (su_key, slot_index) = self.request.get("location").split()
            container.storage_unit = ndb.Key(urlsafe=su_key)
            su = container.storage_unit.get()
            container.slot = su.slots[int(slot_index)]
            container.put()
            urlsafe_key = container.key.urlsafe()

        if urlsafe_key != "":
            self.redirect("/container/view?key=" + urlsafe_key)
        else:
            self.redirect("/")


class ContainerContentForm(webapp2.RequestHandler):
    def get(self):
        urlsafe_key = self.request.get("key")
        c = None
        vials = {}
        if urlsafe_key != "":
            k = ndb.Key(urlsafe=urlsafe_key)
            c = k.get()
            for v in c.query_vials().fetch():
                vials["%d_%d" % (v.x, v.y)] = v

        render(self, "container.html", container=c,  vials=vials)

    def post(self):
        urlsafe_key = self.request.get("key")
        if urlsafe_key != "":
            k = ndb.Key(urlsafe=urlsafe_key)
            c = k.get()
        else:
            c = Container()
            c.owner = users.get_current_user()
            c.size_x = 8
            c.size_y = 8

        c.name = self.request.get("name")
        c.description = self.request.get("description")
        c.put()
        self.redirect("/")


class VialForm(webapp2.RequestHandler):
    def get(self):
        urlsafe_key = self.request.get("key")
        if urlsafe_key != "":
            k = ndb.Key(urlsafe=urlsafe_key)
            v = k.get()
        else:
            container_key = self.request.get("container_key")
            container = ndb.Key(urlsafe=container_key)
            v = Vial(parent=container)
            v.x = int(self.request.get("x"))
            v.y = int(self.request.get("y"))
            v.name = ""
            v.description = ""
            v.creation_date = datetime.date.today()

        render(self, "vial.html", vial=v,
          vial_groups=VialGroup.query().fetch())

    def post(self):
        urlsafe_key = self.request.get("key")
        if urlsafe_key != "":
            k = ndb.Key(urlsafe=urlsafe_key)
            v = k.get()
        else:
            container_key = self.request.get("container_key")
            container = ndb.Key(urlsafe=container_key)
            v = Vial(parent=container)
            v.owner = users.get_current_user()
            v.x = int(self.request.get("x"))
            v.y = int(self.request.get("y"))

        v.name = self.request.get("name")
        v.description = self.request.get("description")
        v.creation_date = datetime.date.today() # TODO: parse from self.reponse
        group_key = self.request.get("group_key")
        v.group = ndb.Key(urlsafe=group_key)
        v.put()
        self.redirect("/container?key=" + v.key.parent().urlsafe())

class VialGroupForm(webapp2.RequestHandler):
    def get(self):
        urlsafe_key = self.request.get("key")
        vg = None
        if urlsafe_key != "":
            k = ndb.Key(urlsafe=urlsafe_key)
            vg = k.get()
        render(self, "vial_group.html", vial_group=vg)

    def post(self):
        urlsafe_key = self.request.get("key")
        if urlsafe_key != "":
            k = ndb.Key(urlsafe=urlsafe_key)
            vg = k.get()
        else:
            vg = VialGroup()
            vg.owner = users.get_current_user()

        vg.name = self.request.get("name")
        vg.description = self.request.get("description")
        vg.color = self.request.get("color")
        vg.creation_date = datetime.date.today() # TODO: parse from self.reponse
        vg.put()
        self.redirect("/")


app = webapp2.WSGIApplication([
        ('/', Index),
        ('/container/(.*)', ContainerForm),
        ('/storage_unit/(.*)', StorageUnitForm),
    ], debug=True)
